﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;

using SubSonic;
using SubSonic.Repository;
using xtra.domain.Subsonic3;

namespace sb.ui.Web {
    [DataContract()]
    public class PageStructureView {
        [DataMember]
        public string Id { get; set; }
        [DataMember]
        public string ParentId { get; set; }
        [DataMember]
        public string URI { get; set; }
        [DataMember]
        public string Title { get; set; }
        [DataMember]
        public string UID { get; set; }
        [DataMember]
        public string Description { get; set; }
    }
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class DataService {
        IRepository repo = new SimpleRepository(SimpleRepositoryOptions.None);
       
        #region Plugins In a Web Page
        [OperationContract]
        public List<PageStructureView> GetPageDOM(int rootId) {
            List<PageStructureView> structure = new List<PageStructureView>();

            structure.Add(new PageStructureView
            {
                Id = "s",
                Title = "Structure"
            });

            (from a in repo.All<Plugins_In_Page>()
             where a.RootPageId == rootId
             join b in repo.All<Plugin>() on a.NodeId equals b.Id
             select new
             {
                 a.Id,
                 a.ParentId,
                 b.Title,
                 b.URI,
                 b.UID
             }).ToList().ForEach(c =>
                 {
                     structure.Add(new PageStructureView
                     {
                         Id = "s" + c.Id.ToString(),
                         ParentId = c.ParentId != null ? "s" + c.ParentId.ToString() : "s",
                         Title = c.Title,
                         URI = c.URI,
                         UID = c.UID
                     });
                 });

            structure.Add(new PageStructureView
            {
                Id = "p",
                Title = "Plugins"
            });

            (from a in repo.All<Plugin>()
             select new
             {
                 a.Id,
                 a.ParentId,
                 a.Title,
                 a.URI,
                 a.UID
             }).ToList().ForEach(c =>
                  {
                      structure.Add(new PageStructureView
                      {
                          Id = "p" + c.Id.ToString(),
                          ParentId = c.ParentId != null ? "p" + c.ParentId.ToString() : "p",
                          Title = c.Title,
                          URI = c.URI,
                          UID = c.UID
                      });
                  });

            return structure;
        }

        [OperationContract]
        public string DeletePageStructureNode(string selectedId) {
            string error = null;
            try {
                if (selectedId.Contains("s")) {
                    int id = int.Parse(selectedId.Replace("s", ""));

                    xtraclubDB db = new xtraclubDB();
                    List<Plugins_In_Page> list = db.struct_GetDecendants(id).ExecuteTypedList<Plugins_In_Page>();
                    list.Reverse();
                    repo.DeleteMany<Plugins_In_Page>(list);
                } else {
                    throw new Exception("cannot be removed");
                }
            } catch (Exception ex) {
                error = ex.Message;
            }
            return error;
        }

        [OperationContract]
        public string InsertNode(int pageId, string pluginId, string targetId) {
            string error = null;
            try {
                var repo = new SimpleRepository(SimpleRepositoryOptions.None);

                Plugins_In_Page item = new Plugins_In_Page();
                item.RootPageId = pageId;
                item.NodeId = int.Parse(pluginId.Replace("p", ""));
                item.ParentId = targetId == "s" ? null : (int?)int.Parse(targetId.Replace("s", ""));

                repo.Add<Plugins_In_Page>(item);

                List<Plugins_In_Page> legs = new List<Plugins_In_Page>();

                (from a in repo.All<Plugin>()
                 where a.ParentId == item.NodeId
                 select a).ToList().ForEach(c =>
                 {
                     legs.Add(new Plugins_In_Page
                     {
                         ParentId = item.Id,
                         NodeId = c.Id,
                         RootPageId = pageId
                     });
                 });

                repo.AddMany<Plugins_In_Page>(legs);

            } catch (Exception ex) {
                error = ex.Message;
            }
            return error;
        }

        #endregion

        #region UIResources
        [OperationContract]
        public List<UIResource> GetUIRecources(string selectedId) {
            List<UIResource> list = null;
            if (selectedId.Contains("s")) {
                int id = int.Parse(selectedId.Replace("s", ""));
                list = repo.Find<UIResource>(a => a.ModuleId == id).ToList();
            }
            return list;
        }

        [OperationContract]
        public string SaveUIText(WebPage page) {
            string error = null;
            try {
                var repo = new SimpleRepository(SimpleRepositoryOptions.None);
                repo.Update<WebPage>(page);
            } catch (Exception ex) {
                error = ex.Message;
            }
            return error;
        }
        #endregion

        #region WEB PAGE
        [OperationContract]
        public List<WebPage> GetPages() {
            return (from a in repo.All<WebPage>()
                    select a).ToList();
        }

        [OperationContract]
        public string SaveWebPage(WebPage page) {
            string error = null;
            try {
                repo.Update<WebPage>(page);
            } catch (Exception ex) {
                error = ex.Message;
            }
            return error;
        }

        [OperationContract]
        public string AddWebPage(WebPage page) {
            string error = null;
            try {
                repo.Add<WebPage>(page);
            } catch (Exception ex) {
                error = ex.Message;
            }
            return error;
        }

        [OperationContract]
        public string DeleteWebPage(int id) {
            string error = null;
            try {
                repo.Delete<WebPage>(id);
            } catch (Exception ex) {
                error = ex.Message;
            }
            return error;
        }
        #endregion
    }
}